package edu.utexas.esel.jgraphpad.archpadplugin.action;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.print.PageFormat;

import javax.swing.tree.TreeModel;

import org.jgraph.graph.GraphLayoutCache;

import com.jgraph.JGraphEditor;
import com.jgraph.editor.JGraphEditorAction;
import com.jgraph.editor.JGraphEditorFile;
import com.jgraph.editor.JGraphEditorModel;
import com.jgraph.pad.JGraphpadFile;
import com.jgraph.pad.action.JGraphpadFileAction;
import com.jgraph.pad.graph.JGraphpadGraphModel;

import edu.utexas.esel.jgraphpad.archpadplugin.Utils;
import edu.utexas.esel.jgraphpad.archpadplugin.graph.ArchPadCellViewFactory;
import edu.utexas.esel.jgraphpad.archpadplugin.model.ArchPadDiagram;
import edu.utexas.esel.jgraphpad.archpadplugin.persistence.ArchPadXMLPersistenceManager;

/**
 * This class defines the file action of the ArchPad plugin.
 *
 * @author svetoslavganov@mail.utexas.edu
 *
 */
public class ArchPadFileAction extends JGraphpadFileAction {

	private static final long serialVersionUID = 1L;

	/**
	 * Specifies the name for the newArchPadDocument action.
	 */
	public static final String NAME_NEW_ARCHPAD_DOCUMENT = "newArchPadDocument";

	/**
	 * Specifies the name for the "new ArchPad diagram" action.
	 */
	public static final String NAME_NEW_ARCHPAD_DIAGRAM = "newArchPadDiagram";

	/**
	 * Specifies the name for the "new ArchPad library" action.
	 */
	public static final String NAME_NEW_ARCHPAD_LIBRARY = "newArchPadLibrary";

	/**
	 * Constructs a new action for the specified name.
	 *
	 * @param name The action name.
	 * @param editor An {@link JGraphEditor} instance used to configure
	 *        the action.
	 */
	public ArchPadFileAction(String name, JGraphEditor editor) {
		super(name, editor);
	}

	/**
	 * Executes the action based on the action name.
	 *
	 * @param event The object that describes the event.
	 */
	public void actionPerformed(ActionEvent event) {
		String name = getName();
		if (NAME_NEW_ARCHPAD_DIAGRAM.equals(name)) {
            doNewDiagram(getPermanentFocusOwnerFile());
		} else if (NAME_NEW_ARCHPAD_DOCUMENT.equals(name)) {
			doNewDocument();
		} else if (NAME_NEW_ARCHPAD_LIBRARY.equals(name)) {
			doNewLibrary();
		}
	}

	/**
	 * Inserts a new empty document into the document model. The name is
	 * assigned automatically using the Document resource string, the number
	 * returned by {@link #getFileCount(boolean)}, and the extension for
	 * ArchPad files - ".archpad.xml".
	 */
	@Override
	protected void doNewDocument() {
		JGraphEditorModel model = editor.getModel();
		int number = getFileCount(false) + 1;
		JGraphpadFile file = new JGraphpadFile(getString("Document") + number
			+ "." + ArchPadXMLPersistenceManager.TYPE_ARCHPAD_XML);
		model.addRoot(file);
		doNewDiagram(file);
	}

	/**
	 * Inserts a new empty ArchPad diagram into the specified file. The name
	 * is assigned automatically using the Diagram resource string and the
	 * number returned by {@link TreeModel#getChildCount(java.lang.Object)}
	 * for the file.
	 *
	 * @param file The file to add the diagram to.
	 */
	@Override
	@SuppressWarnings("unchecked")
	// Required because JGraphPadPro uses raw types.
	protected void doNewDiagram(JGraphEditorFile file) {
		if (!isLibrary(file)) {

			JGraphEditorModel model = editor.getModel();
			int number = model.getChildCount(file) + 1;

			GraphLayoutCache cache = new GraphLayoutCache(
			    new JGraphpadGraphModel(), new ArchPadCellViewFactory(), true);

			ArchPadDiagram newDiagram = new ArchPadDiagram(
				getString("Diagram") + number, cache);

			// Set the graph preferred size to two pages width since the
			// default of one page is quite small.
			PageFormat pageFormat = new PageFormat();
			newDiagram.getProperties().put("graph.preferredSize",
					new Dimension((int) pageFormat.getWidth() * 2,
							(int) pageFormat.getHeight()));
			model.addChild(newDiagram, (JGraphpadFile) file);
		}
	}

	/**
	 * Bundle of all actions in this class.
	 */
	public static class AllActions implements Bundle {

		private JGraphEditorAction[] mAllActions;

		/**
		 * Constructs the action bundle for the specified editor.
		 *
		 * @param editor The enclosing editor for this bundle.
		 */
		public AllActions(JGraphEditor editor) {
			mAllActions = new JGraphEditorAction[3];
			mAllActions[0] =
				new ArchPadFileAction(NAME_NEW_ARCHPAD_DOCUMENT, editor);
			mAllActions[1] =
				new ArchPadFileAction(NAME_NEW_ARCHPAD_DIAGRAM, editor);
			mAllActions[2] =
				new ArchPadFileAction(NAME_NEW_ARCHPAD_LIBRARY, editor);
		}

		public JGraphEditorAction[] getActions() {
			return mAllActions;
		}
 
		public void update() {
			boolean enabled = Utils.isCurrentArchPadDiagram();
			mAllActions[1].setEnabled(enabled);
		}
	}
}